#include <stdio.h>              // standard C libraries
#include <stdlib.h>
#include <cstring>
#include <math.h>
#include <time.h>
#include <iostream>
#include <cutil.h>
#include <cuda.h>
#include <shrUtils.h>

#include "util.h"
#include "houghTransform_kernel.cu"

using namespace std;

__host__ void createImage(MyPoint *);
__host__ void initializeMatrix(int **, int, int);



int main(int argc, char **argv)
{
	MyPoint * d_edgePixels;
	int *accumulator, * d_accumulator;
	accumulator = new int[360*edge_pixels];
	//unsigned int timer_execution = 0;
	hr_timer_t timer_execution;
	for(int i = 0; i < 360*edge_pixels; i++)
			accumulator[i] = 0;
			
	int value[1];
	int * d_value;
	
	value[0] = 0;
	
	MyPoint edgePixels[edge_pixels];
	
	//initializeMatrix(accumulator, 360,20000);
	createImage(edgePixels);
	
	cudaSetDevice(1);
	
	//printf("size: %d\n", sizeof(MyPoint)*edge_pixels);
	
	//CUT_SAFE_CALL( cutCreateTimer(&timer_execution) );
	//CUT_SAFE_CALL( cutStartTimer(timer_execution) );
	
	CUDA_SAFE_CALL( cudaMalloc((void**)&d_edgePixels, sizeof(MyPoint)*edge_pixels) );
	CUDA_SAFE_CALL( cudaMalloc((void**)&d_accumulator, sizeof(int)*360*edge_pixels) );
	CUDA_SAFE_CALL( cudaMalloc((void**)&d_value, sizeof(int)) );
	CUDA_SAFE_CALL( cudaMemcpy(d_edgePixels, edgePixels, sizeof(MyPoint)*edge_pixels, cudaMemcpyHostToDevice) );
	CUDA_SAFE_CALL( cudaMemcpy(d_accumulator, accumulator, sizeof(int)*360*edge_pixels, cudaMemcpyHostToDevice) );
	CUDA_SAFE_CALL( cudaMemcpy(d_value, value, sizeof(int), cudaMemcpyHostToDevice) );
	
		//set the dimensions for the block and for the grid
	dim3 dimBlock( BLOCK_SIZE );
	dim3 dimGrid(  (edge_pixels / dimBlock.x) + 1 );
	
	//printf("x: %d, y: %d\n", dimBlock.x, dimBlock.y);
	
		timer_start(&timer_execution);
	
	
	//CUT_SAFE_CALL( cutCreateTimer(&timer_execution) );
	//CUT_SAFE_CALL( cutStartTimer(timer_execution) );
	
	houghTransform<<<dimGrid, dimBlock>>>(d_edgePixels, d_accumulator, d_value);
	cudaThreadSynchronize();
	
	//CUT_SAFE_CALL( cutStopTimer(timer_execution) );
	//printf("Execution time: %f seconds\n", cutGetTimerValue(timer_execution)/1000.0);
	
	//CUDA_SAFE_CALL( cudaMemcpy(value, d_value,  sizeof(int), cudaMemcpyDeviceToHost) );
	
	timer_end(&timer_execution);
	printf("Execution time: %f seconds\n", compute_secs(&timer_execution.elapsed));
	
	cudaFree( d_edgePixels );
	cudaFree( d_accumulator );

	return 0;
}

__host__ void createImage(MyPoint * edgePixels)
{
	int x, y, i;
	for(i =0, x = 200, y = 200; x < edge_pixels + 200; x++, y++, i++)
	{
		MyPoint temp_pt;
				
		temp_pt.x = x;
		temp_pt.y = y;
		edgePixels[i] = temp_pt;
	}	
}
__host__ void initializeMatrix(int **matrix, int numRows, int numCols) 
{
	for(int i = 0; i < numRows; i++)
		matrix[i] = new int[numCols];

	for(int i = 0; i < numRows; i++)
		for(int j = 0; j < numCols; j++)
			matrix[i][j] = 0;
}

